﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Nuzzle.Protocol
{
    public class Formatter
    {
        private List<Byte> _byteList = new List<Byte>();

        public Byte[] get_Data
        {
            get { return _byteList.ToArray(); }
        }

        public int ID
        {
            get { return _packetID; }
        }

        public int Length
        {
            get { return _packetLength; }
        }

        private int _packetID;
        private int _packetLength = 0;

        private Boolean isInit = false;

        public Boolean is_Init
        {
            get { return isInit; }
        }

        public Formatter(int id)
        {
            _packetID = id;
        }

        public void WriteByte(Byte value)
        {
            _byteList.Add(value);
        }

        public void WriteUShort(ushort value)
        {
            byte[] Bytes = new byte[2];
            new BinaryWriter(new MemoryStream(Bytes)).Write(value);
            _byteList.AddRange(Bytes.Reverse());
        }

        public Formatter Pack(byte[] byteArray)
        {
            int loc4 = computeTypeLen(byteArray);
            int loc5;
            int loc6;

            WriteUShort((ushort)subComputeStaticHeader(loc4));

            switch (loc4)
            {
                case 1:
                    WriteByte((Byte)byteArray.Length);
                    break;

                case 2:
                    WriteUShort((ushort)byteArray.Length);
                    break;

                case 3:
                    loc5 = byteArray.Length >> 16 & 255;
                    loc6 = byteArray.Length & 65535;
                    WriteByte((Byte)loc5);
                    WriteUShort((ushort)loc6);
                    break;
            }
            _byteList.AddRange(byteArray);

            return this;
        }

        private int computeTypeLen(byte[] data)
        {
            if (data.Length > 65535) { return 3; }
            if (data.Length > 255) { return 2; }
            if (data.Length > 0) { return 1; }
            return 0;
        }

        private int subComputeStaticHeader(int compute)
        {
            return (int)_packetID << 2 | compute;
        }
    }
}
